package com.oa.shiro;

import com.oa.mapper.PermissionMapper;
import com.oa.pojo.Permission;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author Str
 * @Date 2021/12/17 14:47
 * @Description :
 * 这个类是为了从数据库获取映射地址和权限，
 * 设置到spring-shiro.xml的过滤器链中，
 * 其实一个个手动写进过滤器链也是一样的，但会很麻烦
 */
public class FilterDataSource {

    @Autowired
    private PermissionMapper PermissionMapper;

    //{1}模拟一个假数据库表 [已废弃] [12-08 16:40]

    //{2.1}-这是过滤器的定义(Map)
    private Map<String,String> definitions = new LinkedHashMap();
    //{2.2}-这是过滤器的定义(Map)
    private String regex = "\\s*([^\\s]+)\\s*=\\s*([^\\s]+)\\s*";

    //{3}去除空白字符用的
    private String[] trimSpace(String line, String regex ){
        //{1}根据正则表达式生成一个编译器
        //这导入这个包: java.util.regex.Pattern
        Pattern cmp = Pattern.compile(regex);
        //{2}得到一个匹配器
        Matcher mat = cmp.matcher( line );
        if( !mat.matches() ){
            throw new RuntimeException("配置格式有误。");
        }
        //{3}返回一个字符串数组。
        return new String[]{
                mat.group(1), mat.group(2)
        };
    }

    //{3}Main 不要了。 [12-08 16:40]

    //{4}设置匿名就可以访问的资源
	/*
		目的为了解析 xml 中的以下内容:
		/User/showLogin = anon
		/User/login = anon
		/static/** = anon
	 */
    public void setAnonymousFilter(String definition ){
        String[] lines = definition.split("\n");
        for(String L : lines){
            L = L.trim();     //去除前后的空格
            if(L.length()==0) continue;
            //{1}裁掉里面多余的空白字符
            String[] data = trimSpace(L,regex);
            System.out.printf("[%s]=[%s]\n", data[0], data[1]);
            //{2}设置到  map 中。
            definitions.put(data[0], data[1]);
        }
    }

    //{5}提供给外部获取过滤器链的 Map
    public Map getFilterDefinitions(){
        //{1}调取数据库中的数据。[获取系统菜单权限]
        Set<Permission> sysPerms = PermissionMapper.getSysPermission();


        //数据库中的格式: user:save
        //我们要封装成这种格式: perms[user:save]
        for (Permission p : sysPerms) {
            StringBuffer sb = new StringBuffer("perms[");
            sb.append( p.getPermission() );
            sb.append("]");
            definitions.put( p.getMapping(), sb.toString());

//            System.out.printf("%s=%s\n", p.getMapping(), sb.toString() );
        }

        //+---------------------[分界线]------------------------+
        //{3}补多一个过滤器(需要登录的资源)。
        definitions.put("/**","authc");

        System.out.println("+-------------------[OA系统权限]-----------------------+");
        itaterate( definitions );
        System.out.println("+-------------------[OA系统权限]-----------------------+");
        //{4}返回 map
        return definitions;
    }

    private void itaterate(Map<String, String> definitions) {
        Set<String> keys = definitions.keySet();
        for (String k : keys) {
            String val = definitions.get(k);
            System.out.printf("%s = %s\n", k, val );
        }
    }

}